package com.iafme.configuration;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.zhxu.bs.BeanSearcher;
import cn.zhxu.bs.operator.InList;
import cn.zhxu.bs.util.MapUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.iafme.dto.req.CertificateOrderReqDTO;
import com.iafme.dto.req.FileReqDTO;
import com.iafme.dto.res.CourserResDTO;
import com.iafme.model.*;
import com.iafme.properties.PayProperties;
import com.iafme.properties.ScanPayReq;
import com.iafme.dto.req.ExamReqDTO;
import com.iafme.dto.req.OrderPayReqDTO;
import com.iafme.service.*;
import com.iafme.utils.AdmissionNumUtil;
import com.iafme.utils.ExamSignUtils;
import com.systemframework.constants.Constants;
import com.systemframework.exception.ResultException;
import com.systemframework.pay.model.PayOrderRequestDTO;
import com.systemframework.pay.service.impl.AlPay;
import com.systemframework.pay.service.impl.WxPay;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.sql.Wrapper;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * @author summer
 * @version 1.0
 * @date 2025/2/8 09:38
 */
@Component
@AllArgsConstructor
public class PayConfiguration {


    private final WxPay wxPay;

    private final PayProperties payProperties;

    private final AlPay alPay;

    private final IExamService examService;

    private final ILevelService levelService;

    private final IOrderService orderService;

    private final IShowingsService showingsService;

    private final OrderCourseService orderCourseService;

    private final CourseService courseService;

    private final BeanSearcher beanSearcher;

    private final RedemptionService redemptionService;



    public ScanPayReq payCode(OrderPayReqDTO orderPayReqDTO, HttpServletRequest request){
        Showings showings = showingsService.getById(orderPayReqDTO.getShowingsId());
        Exam exam=new Exam();
        exam.setLevelId(orderPayReqDTO.getLevelId());
        exam.setProjectId(orderPayReqDTO.getProjectId());
        exam.setSessionId(orderPayReqDTO.getShowingsId());
        exam.setMemberId(StpUtil.getLoginIdAsInt());
        exam.setStatus(Constants.ZERO);
        examService.save(exam);
        Order order=new Order();
        order.setExamId(exam.getId());
        order.setPayType(orderPayReqDTO.getPayType());
        order.setProjectId(orderPayReqDTO.getProjectId());
        order.setLevelId(orderPayReqDTO.getLevelId());
        order.setSessionId(orderPayReqDTO.getShowingsId());
        order.setExamTime(LocalDate.now());
        order.setMemberId(StpUtil.getLoginIdAsInt());
        order.setStatus(Constants.ZERO);
        List<Integer> ids = orderPayReqDTO.getCourseIds();
        StringBuilder text= new StringBuilder();
        LambdaQueryWrapper<Course> in = Wrappers.lambdaQuery(Course.class).in(Course::getId, ids);
        List<Course> courseList = courseService.list(in);
        for(Course course:courseList){
            text.append("_").append(course.getName());
        }
        order.setDetails(showings.getName()+text);
        order.setOrderNo(AdmissionNumUtil.orderNum());
        orderService.save(order);
        //订单对应模块课程
        BigDecimal amount = BigDecimal.ZERO;
        List<OrderCourse> orderCourseList= ListUtil.list(true);
        for(Course course:courseList){
            OrderCourse orderCourse=new OrderCourse();
            orderCourse.setOrderId(order.getId());
            orderCourse.setCourseId(course.getId());
            orderCourseList.add(orderCourse);
            amount=amount.add(course.getAmount());
        }

        orderCourseService.saveBatch(orderCourseList);

        if(orderPayReqDTO.getPayType().equals(3)){
            redemptionService.checkRedemption(orderPayReqDTO.getCode());
            orderService.updateOrderStatus(order.getOrderNo());
            ScanPayReq scanPayReq=new ScanPayReq();
            scanPayReq.setCodeUrl("");
            scanPayReq.setOrderNo(order.getOrderNo());
            return  scanPayReq;
        }
        order.setCost(amount);
        orderService.updateById(order);
        return scanPayReq(0,order.getOrderNo(), showings.getName(),amount.toString(),orderPayReqDTO.getPayType(),request,payProperties.getWxNotifyUrl(),payProperties.getAliNotifyUrl());
    }

    private final OrderNoTypeService orderNoTypeService;

    private ScanPayReq scanPayReq(Integer type,String orderNo,String productName,String productPrice, Integer payType, HttpServletRequest request,String wxNotifyUrl,String aliNotifyUrl){
        ScanPayReq scanPayReq=new ScanPayReq();
        PayOrderRequestDTO payOrderRequestDTO=new PayOrderRequestDTO();
        payOrderRequestDTO.setOrderNo(orderNo);
        payOrderRequestDTO.setProductPrice(productPrice);
        payOrderRequestDTO.setProductName(productName);
        payOrderRequestDTO.setProductId(AdmissionNumUtil.orderNum());
        if(payType.equals(Constants.ONE)){
            payOrderRequestDTO.setNotifyUrl(wxNotifyUrl);
            scanPayReq.setCodeUrl(wxPay.nativePay(payOrderRequestDTO, request));
        }else if(payType.equals(Constants.TWO)){
            payOrderRequestDTO.setNotifyUrl(aliNotifyUrl);
            scanPayReq.setCodeUrl(alPay.nativePay(payOrderRequestDTO, request));
        }
        scanPayReq.setOrderNo(orderNo);
        OrderNoType orderNoType=new OrderNoType();
        orderNoType.setOrderNo(orderNo);
        orderNoType.setType(type);
        orderNoTypeService.save(orderNoType);
        return scanPayReq;
    }

    private final  CertificateOrderService certificateOrderService;

    private final  CertificateOrderImageService orderImageService;

    private final CertificateOrderItemService orderItemService;

    private final CertificateService certificateService;

    public ScanPayReq certificatePayCode(CertificateOrderReqDTO certificateOrderReqDTO, HttpServletRequest request) {
        LambdaQueryWrapper<Certificate> eq = Wrappers.lambdaQuery(Certificate.class).in(Certificate::getId, certificateOrderReqDTO.getCertificateIds());
        List<Certificate> certificateList = certificateService.list(eq);
        Project project = projectService.getById(certificateOrderReqDTO.getProjectId());
        Level level = levelService.getById(certificateOrderReqDTO.getLevelId());
        CertificateOrder certificateOrder= Convert.convert(CertificateOrder.class, certificateOrderReqDTO);
        certificateOrder.setOrderNo(AdmissionNumUtil.orderNum());
        certificateOrder.setMemberId(StpUtil.getLoginIdAsInt());
        StringBuilder text= new StringBuilder(project.getName() + "_"+level.getName()+"(");
        for(Certificate certificate:certificateList){
            text.append(certificate.getName()).append("_");
        }
        String aa=text.toString().substring(0,text.length()-1)+")";
        certificateOrder.setPayType(certificateOrderReqDTO.getPayType());
        certificateOrder.setDetails(aa);
        certificateOrderService.save(certificateOrder);
        //保存图片
        List<FileReqDTO> fileList = certificateOrderReqDTO.getFileList();
        List<CertificateOrderImage> imageList=ListUtil.list(true);
        fileList.forEach(file->{
            CertificateOrderImage orderImage=new CertificateOrderImage();
            orderImage.setImage(file.getUrl());
            orderImage.setOrderId(certificateOrder.getId());
            imageList.add(orderImage);
        });
        orderImageService.saveBatch(imageList);
        //保存证书
        certificateOrderReqDTO.getCertificateIds().forEach(certificateId->{
            CertificateOrderItem orderItem=new CertificateOrderItem();
            orderItem.setOrderId(certificateOrder.getId());
            orderItem.setCertificateId(certificateId);
            orderItemService.save(orderItem);
        });

        if(certificateOrderReqDTO.getPayType().equals(3)){
            redemptionService.checkRedemption(certificateOrderReqDTO.getCode());
            certificateOrderService.updateStatus(certificateOrder.getOrderNo());
            ScanPayReq scanPayReq=new ScanPayReq();
            scanPayReq.setCodeUrl("");
            scanPayReq.setOrderNo(certificateOrder.getOrderNo());
            return  scanPayReq;
        }


        return scanPayReq(1,certificateOrder.getOrderNo(), project.getName()+"_"+level.getName(),
                certificateOrder.getAmount().toString(), certificateOrder.getPayType(), request, payProperties.getWxNotifyUrl(), payProperties.getAliNotifyUrl());
    }

    private final IProjectService projectService;

 }
